﻿using System;
using System.Threading;
// ReSharper disable InconsistentNaming


public partial struct ETTask
{
    public static ETTask CompletedTask => new();

    public static ETTask FromException(Exception ex)
    {
        ETTaskAwaiter tcs = new ETTaskAwaiter();
        tcs.TrySetException(ex);
        return tcs.Task;
    }

    public static ETTask<T> FromException<T>(Exception ex)
    {
        var tcs = new ETTaskAwaiter<T>();
        tcs.TrySetException(ex);
        return tcs.Task;
    }

    public static ETTask<T> FromResult<T>(T value)
    {
        return new ETTask<T>(value);
    }

    public static ETTask FromCanceled()
    {
        return CanceledETTaskCache.Task;
    }

    public static ETTask<T> FromCanceled<T>()
    {
        return CanceledETTaskCache<T>.Task;
    }

    public static ETTask FromCanceled(CancellationToken token)
    {
        ETTaskAwaiter tcs = new ETTaskAwaiter();
        tcs.TrySetException(new OperationCanceledException(token));
        return tcs.Task;
    }

    public static ETTask<T> FromCanceled<T>(CancellationToken token)
    {
        var tcs = new ETTaskAwaiter<T>();
        tcs.TrySetException(new OperationCanceledException(token));
        return tcs.Task;
    }

    private static class CanceledETTaskCache
    {
        public static readonly ETTask Task;

        static CanceledETTaskCache()
        {
            ETTaskAwaiter tcs = new ETTaskAwaiter();
            tcs.TrySetCanceled();
            Task = tcs.Task;
        }
    }

    private static class CanceledETTaskCache<T>
    {
        public static readonly ETTask<T> Task;

        static CanceledETTaskCache()
        {
            var taskCompletionSource = new ETTaskAwaiter<T>();
            taskCompletionSource.TrySetCanceled();
            Task = taskCompletionSource.Task;
        }
    }
}

internal static class CompletedTasks
{
    public static readonly ETTask<bool> True = ETTask.FromResult(true);
    public static readonly ETTask<bool> False = ETTask.FromResult(false);
    public static readonly ETTask<int> Zero = ETTask.FromResult(0);
    public static readonly ETTask<int> MinusOne = ETTask.FromResult(-1);
    public static readonly ETTask<int> One = ETTask.FromResult(1);
}
